## 4.5. Debugging Scripts

Because CGI scripts run underneath Apache, it can be awkward to debug them. When a script fails, you normally don't get much help on the browser screen, but the error log can be much more informative and is the first thing to check (by default, it is .../logs/error_log, but you can set it to what you like with the `ErrorLog` directive).

If you are programming your script in Perl, the CGI::Carp module can be helpful. However, most other languages[39] you might want to use for CGI do not have anything so useful. If you are programming in a high-level language and want to run a debugger, it is usually impossible to do so directly. However, it is possible to simulate the environment in which an Apache script runs. The first thing to do is to become the user that Apache runs as (often webserv). Then, remember that Apache always runs a script in the script's own directory, so go to that directory. Next, Apache passes most of the information a script needs in environment variables. Determine what those environment variables should be (either by thinking about it or, more reliably, by temporarily replacing your CGI with one that executes env, as illustrated above), and write a little script that sets them, then runs your CGI (possibly under a debugger). Since Apache sets a vast number of environment variables, it is worth knowing that most CGI scripts hardly use any -- usually only `QUERY_STRING` (or `PATH_INFO`, less often). Of course, if you wrote the script and all its libraries, you'll know what it used, but that isn't always the case. So, to give a concrete example, suppose we wanted to debug the mycgi script given earlier. We'd go into .../cgi-bin and write a script called, say, debug.cgi, that looked something like this:

> [39]We'll include ordinary shell scripts as "languages," which, in many senses, they are.

>     #!/bin/sh
>     QUERY_STRING='2315_order=20&2316_order=10&card_type=Amex'
>     export QUERY_STRING
>     gdb myecho

We'd run it by typing:

>     chmod +x debug.cgi
>     ./debug.cgi

Once gdb came up, we'd hit `r<CR>` and the script would run.[40]

> [40]Obviously, if we really wanted to debug it, we'd set some breakpoints first.

A couple of things may trip you up here. The first is that if the script expects the `POST` method -- that is, if `REQUEST_METHOD` is set to `POST` -- the script will (if it is working correctly) expect the `QUERY_STRING` to be supplied on its standard input rather than in the environment. Most scripts use a library to process the query string, so the simple solution is to not set `REQUEST_METHOD` for debugging, or to set it to `GET` instead. If you really must use `POST`, then the script would become:

>     #!/bin/sh
>     REQUEST_METHOD=POST
>     export REQUEST_METHOD
>     myecho << EOF
>     2315_order=20&2316_order=10&card_type=Amex
>     EOF

Note that this time we didn't run the debugger, for the simple reason that the debugger also wants input from standard input. To accommodate that, put the query string in some file and tell the debugger to use that file for standard input (in gdb 's case, that means type `r` `<` yourfile).

The second tricky thing occurs if you are using Perl and the standard Perl module CGI.pm. In this case, CGI helpfully detects that you aren't running under Apache and prompts for the query string. It also wants the individual items separated by newlines instead of ampersands. The simple solution is to do something very similar to the solution to the `POST` problem we just discussed, except with newlines.

Copyright © 2001 O'Reilly & Associates. All rights reserved.